import 'dart:async';
import 'dart:io';
import 'dart:ui' as ui show Codec, FrameInfo, Image;
import 'package:audioplayers/audioplayers.dart';
import 'package:base_lib/common/index.dart';
import 'package:base_lib/theme/theme_global.dart';
import 'package:base_lib/utils/log.dart';
import 'package:doctor_inquiry_lib/bus.dart';
import 'package:doctor_inquiry_lib/constant/constant.dart';
import 'package:doctor_inquiry_lib/inquiry_plugin.dart';
import 'package:doctor_inquiry_lib/video/trtc_video_page.dart';
import 'widget/message_item.dart';
import 'widget/chat_bottom.dart';
import 'widget/expanded_viewport.dart';
export 'widget/message_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'entity/MessageNormal.dart';
import 'package:uuid/uuid.dart';
import 'package:doctor_login_lib/login/entity/doctor_login_entity.dart'
    as DoctorBean;
import 'package:doctor_inquiry_lib/chat_list/entity/im_chat_list_entity.dart'
    as ChatListBean;
import 'package:doctor_inquiry_lib/chat_list/entity/doctor_patient_entity.dart'
    as DoctorPatientBean;
import 'entity/msg_list_entity.dart' as MsgBean;

///单聊-聊天室
class ChatC2CPage extends StatefulWidget {
  final Parameters parameters;

  ChatC2CPage(this.parameters);

  @override
  _ChatC2CPageState createState() => _ChatC2CPageState();
}

class _ChatC2CPageState extends BaseThemeState<ChatC2CPage> {
  final ScrollController listScrollController = new ScrollController();
  List<WMessage> mListMessage = new List();

  //https://stackoverflow.com/questions/50733840/trigger-a-function-from-a-widget-to-a-state-object/50739019#50739019
  final changeNotifier = new StreamController.broadcast();
  AudioPlayer mAudioPlayer = AudioPlayer();
  bool isPlayingAudio = false;
  String mPlayingPosition = "";
  bool isShowLoading = false;
  bool isBottomLayoutShowing = false;

  @override
  void dispose() {
    changeNotifier.close();
    disposeBusListener();
    super.dispose();
  }

  getHistoryMessage() async {
    // FLog("获取历史消息");
    InquiryPlugin.getInstance()
        .getC2CMsgList(chatData.patientID, 20, mListMessage.isEmpty);
  }

  ChatListBean.ImChatListEntity chatData;
  DoctorBean.DoctorUser doctorUser;

  @override
  void initState() {
    super.initState();
    listScrollController.addListener(() {
      if (listScrollController.position.pixels ==
          listScrollController.position.maxScrollExtent) {
        isShowLoading = true;
        doRefresh();
        getHistoryMessage();
      }
    });

    initBusListener();

    chatData = widget.parameters.getObj('chat');
    doctorUser = widget.parameters.getObj('doctor');

    InquiryPlugin.getInstance().markC2CMessageAsRead(chatData.patientID);

    getHistoryMessage();
  }

  void initBusListener() {
    globalBus.on(InquiryPlugin.BUS_KEY_REFRESH_CHAT_MSG_LIST, (arg) {
      if (arg == null) {
        // FLog("获取单聊历史消息 空列表");
        if (mListMessage.last is WHintMessage &&
            (mListMessage.last as WHintMessage).hint == '没有更多记录') {
          //不用添加描述信息
        } else {
          mListMessage.add(WHintMessage(hint: '没有更多记录'));
        }
      } else {
        // FLog("获取单聊历史消息    $arg");
        // mListMessage.clear();
        arg.forEach((element) {
          var bean = MsgBean.MsgEntity.MsgBean2WMessage(
              element, chatData.patientData, doctorUser);
          mListMessage.add(bean);
        });
      }

      isShowLoading = false;
      doRefresh();
    });

    globalBus.on(InquiryPlugin.BUS_KEY_REFRESH_CHAT_MSG, (arg) {
      // FLog("新消息到达    $arg");
      var msg = MsgBean.MsgEntity.MsgBean2WMessage(
          arg, chatData.patientData, doctorUser);
      var customMsgID = msg.customMsgID;
      if (customMsgID != null && customMsgID.isNotEmpty) {
        int itemIndex = mListMessage.indexWhere((element) {
          return element.customMsgID == customMsgID;
        });
        FLog("消息发送    $itemIndex");
        if (itemIndex != -1) {
          FLog('消息发送成功  ${mListMessage[itemIndex].msgType}');
          mListMessage[itemIndex].state = WMessageState.send_succeed;
        }
      } else {
        mListMessage.insert(0, msg);
        InquiryPlugin.getInstance().markC2CMessageAsRead(chatData.patientID);
      }
      listScrollController.animateTo(0.00,
          duration: Duration(milliseconds: 1), curve: Curves.easeOut);
      doRefresh();
    });

    globalBus.on(InquiryPlugin.BUS_KEY_REFRESH_MSG_SEND_PROGRESS, (arg) {
      // FLog("刷新消息发送进度    $arg");
      //{"msgID":"88ae1ee8-441c-4b0b-85e9-fc9482871017","progress":100}
    });

    globalBus.on(InquiryPlugin.BUS_KEY_REFRESH_MSG_SEND_FAILED, (arg) {
      // FLog("消息发送失败    $arg");
      var customMsgID = '';
      if (customMsgID != null && customMsgID.isNotEmpty) {
        int itemIndex = mListMessage.indexWhere((element) {
          return element.customMsgID == customMsgID;
        });
        // FLog("消息发送失败    $itemIndex");
        if (itemIndex != -1) {
          mListMessage[itemIndex].state = WMessageState.send_failed;
          doRefresh();
        }
      }
    });

    globalBus.on(InquiryPlugin.BUS_KEY_REFRESH_MSG_SOUND_PATH, (arg) {
      // FLog("刷新语音消息url    $arg");
      var index =
          mListMessage.indexWhere((element) => arg['msgID'] == element.msgID);
      if (index != -1) {
        (mListMessage[index] as WVoiceMessage)..path = arg['path'];
        doRefresh();
      }
    });
  }

  void disposeBusListener() {
    globalBus.off(InquiryPlugin.BUS_KEY_REFRESH_CHAT_MSG_LIST);

    globalBus.off(InquiryPlugin.BUS_KEY_REFRESH_CHAT_MSG);

    globalBus.off(InquiryPlugin.BUS_KEY_REFRESH_MSG_SEND_PROGRESS);

    globalBus.off(InquiryPlugin.BUS_KEY_REFRESH_MSG_SEND_FAILED);

    globalBus.off(InquiryPlugin.BUS_KEY_REFRESH_MSG_SOUND_PATH);
  }

  void doRefresh() {
    setState(() {});

    Future.delayed(Duration(milliseconds: 100), () {
      mListMessage.forEach((element) {
        if (element is WVoiceMessage) {
          if (element.path?.isEmpty ?? true)
            InquiryPlugin.getInstance().getSoundPath(element.msgID);
        }
      });
    });
  }

  @override
  Widget buildChild(BuildContext context, MTheme theme) {
    return Material(
        child: new WillPopScope(
      onWillPop: () {
        FocusScope.of(context).requestFocus(FocusNode());
        changeNotifier.sink.add(null);
        Navigator.pop(context);
        return null;
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(
            chatData?.patientData?.personName ?? '用户名',
            style: TextStyle(fontSize: 16, color: Colors.white),
          ),
          elevation: 0,
          centerTitle: true,
        ),
        resizeToAvoidBottomInset: false,
        backgroundColor: Color(0xffEDEDED),
        body: SafeArea(
          child: Column(
            children: <Widget>[
              Expanded(
                child: GestureDetector(
                  behavior: HitTestBehavior.translucent,
                  onTap: () {
                    //  点击顶部空白处触摸收起键盘
                    FocusScope.of(context).requestFocus(FocusNode());
                    changeNotifier.sink.add(null);
                  },
                  child: new ScrollConfiguration(
                    behavior: _MyBehavior(),
                    child: Scrollable(
                      physics: AlwaysScrollableScrollPhysics(),
                      controller: listScrollController,
                      axisDirection: AxisDirection.up,
                      viewportBuilder: (context, offset) {
                        return ExpandedViewport(
                          offset: offset,
                          axisDirection: AxisDirection.up,
                          slivers: <Widget>[
                            SliverExpanded(),
                            SliverList(
                              delegate: SliverChildBuilderDelegate(
                                (c, i) {
                                  final GlobalKey<ChatMessageItemState>
                                      mMessageItemKey = GlobalKey();
                                  mMessageItemKey.currentState
                                      ?.methodInChild(false, "");
                                  ChatMessageItem mChatItem = ChatMessageItem(
                                    key: mMessageItemKey,
                                    mMessage: mListMessage[i],
                                    onAudioTap: (WVoiceMessage voiceMsg) {
                                      if (voiceMsg.path == null ||
                                          voiceMsg.path.isEmpty) {
                                        InquiryPlugin.getInstance()
                                            .getSoundPath(voiceMsg.msgID);
                                      } else
                                        doPlayAudio(mMessageItemKey,
                                            voiceMsg.path, voiceMsg);
                                    },
                                    onCardTap: (WCardMessage msg) {
                                      //todo
                                    },
                                  );
                                  return mChatItem;
                                },
                                childCount: mListMessage.length,
                              ),
                            ),
                            SliverToBoxAdapter(
                              child: isShowLoading
                                  ? Container(
                                      margin: EdgeInsets.only(top: 5),
                                      height: 50,
                                      child: Center(
                                        child: SizedBox(
                                          width: 25.0,
                                          height: 25.0,
                                          child: CircularProgressIndicator(
                                            strokeWidth: 3,
                                          ),
                                        ),
                                      ),
                                    )
                                  : new Container(),
                            ),
                          ],
                        );
                      },
                    ),
                  ),
                ),
              ),
              ChatBottomInputWidget(
                  onCallClick: () {
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) {
                      return TVideoPage(
                        loginUser: doctorUser.keyID,
                        user: chatData.patientID,
                        nick: chatData.patientData.personName,
                        faceImg: chatData.patientData.faceImage,
                      );
                    }));
                  },
                  onVideoCallClick: () {
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) {
                      return TVideoPage(
                        loginUser: doctorUser.keyID,
                        user: chatData.patientID,
                        nick: chatData.patientData.personName,
                        faceImg: chatData.patientData.faceImage,
                      );
                    }));
                  },
                  onExamineClick: () {},
                  onRpClick: () {},
                  onTransferClick: () {},
                  onEndChatClick: () {},

                  ///消息
                  shouldTriggerChange: changeNotifier.stream,
                  onSendCallBack: (value) {
                    print("发送的文字:" + value);
                    var tempID = Uuid().v4() + "";

                    final WTextMessage mMessage = new WTextMessage();
                    mMessage.customMsgID = tempID;
                    mMessage.text = value;
                    mMessage.from = WUserInfo(
                        id: doctorUser.keyID,
                        username: doctorUser.phone,
                        nick: doctorUser.doctorName,
                        headUrl: doctorUser.faceImage);
                    mMessage.msgType = WMessageType.text;
                    mMessage.isSend = true;
                    mMessage.state = WMessageState.sending;
                    mListMessage.insert(0, mMessage);
                    listScrollController.animateTo(0.00,
                        duration: Duration(milliseconds: 1),
                        curve: Curves.easeOut);
                    doRefresh();

                    MsgBean.MsgEntity sendTextMsg = new MsgBean.MsgEntity();
                    sendTextMsg
                      ..customMsgID = tempID
                      ..textElem = value
                      ..userID = chatData.patientData.keyId
                      ..elemType = 'text';
                    InquiryPlugin.getInstance().sendMsg(sendTextMsg);
                  },
                  onImageSelectCallBack: (value) {
                    File image = new File(
                        value.path); // Or any other way to get a File instance.
                    Future<ui.Image> decodedImage =
                        decodeImageFromList(image.readAsBytesSync());

                    decodedImage.then((result) {
                      print("图片的宽:" + "${result.width}");
                      print("图片的高:" + "${result.height}");
                    });

                    var tempID = Uuid().v4() + "";
                    final WImageMessage mMessage = new WImageMessage();
                    mMessage.customMsgID = tempID;
                    mMessage.msgType = WMessageType.image;
                    mMessage.isSend = true;
                    mMessage.thumbPath = value.path;
                    mMessage.from = WUserInfo(
                        id: doctorUser.keyID,
                        username: doctorUser.phone,
                        nick: doctorUser.doctorName,
                        headUrl: doctorUser.faceImage);
                    mMessage.state = WMessageState.sending;
                    mListMessage.insert(0, mMessage);
                    listScrollController.animateTo(0.00,
                        duration: Duration(milliseconds: 1),
                        curve: Curves.easeOut);
                    doRefresh();

                    MsgBean.MsgEntity sendImgMsg = new MsgBean.MsgEntity();
                    sendImgMsg
                      ..customMsgID = tempID
                      ..imgPath = value.path
                      ..userID = chatData.patientData.keyId
                      ..elemType = 'image';
                    InquiryPlugin.getInstance().sendMsg(sendImgMsg);
                  },
                  onAudioCallBack: (value, duration) {
                    var tempID = Uuid().v4() + "";
                    final WVoiceMessage mMessage = new WVoiceMessage();
                    mMessage.customMsgID = tempID;
                    mMessage.msgType = WMessageType.voice;
                    mMessage.isSend = true;
                    mMessage.path = value.path;
                    mMessage.duration = duration;
                    mMessage.from = WUserInfo(
                        id: doctorUser.keyID,
                        username: doctorUser.phone,
                        nick: doctorUser.doctorName,
                        headUrl: doctorUser.faceImage);
                    mMessage.state = WMessageState.sending;
                    mListMessage.insert(0, mMessage);
                    listScrollController.animateTo(0.00,
                        duration: Duration(milliseconds: 1),
                        curve: Curves.easeOut);
                    doRefresh();

                    MsgBean.MsgEntity sendVoiceMsg = new MsgBean.MsgEntity();
                    sendVoiceMsg
                      ..customMsgID = tempID
                      ..soundPath = value.path
                      ..soundDuration = duration
                      ..userID = chatData.patientData.keyId
                      ..elemType = 'voice';
                    InquiryPlugin.getInstance().sendMsg(sendVoiceMsg);
                  }),
            ],
          ),
        ),
      ),
    ));
  }

  void doPlayAudio(GlobalKey<ChatMessageItemState> mMessageItemKey, String path,
      WMessage wMessage) {
    if (isPlayingAudio) {
      isPlayingAudio = false;
      mMessageItemKey.currentState?.methodInChild(false, mPlayingPosition);
      mAudioPlayer.release(); // manually release when no longer needed
      mPlayingPosition = "";
      doRefresh();
    } else {
      Future<int> result = mAudioPlayer.play(path,
          isLocal: (!path.contains('http://') && !path.contains("https://")));
      mAudioPlayer.onPlayerCompletion.listen((event) {
        mMessageItemKey.currentState?.methodInChild(false, mPlayingPosition);
        isPlayingAudio = false;
        mPlayingPosition = "";
      });

      isPlayingAudio = true;
      mPlayingPosition = wMessage.msgID;
      mMessageItemKey.currentState?.methodInChild(true, mPlayingPosition);
    }
  }
}

class _MyBehavior extends ScrollBehavior {
  @override
  Widget buildViewportChrome(
      BuildContext context, Widget child, AxisDirection axisDirection) {
    if (Platform.isAndroid || Platform.isFuchsia) {
      return child;
    } else {
      return super.buildViewportChrome(context, child, axisDirection);
    }
  }
}
